package esb.util.framework;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.jibx.runtime.BindingDirectory;
import org.jibx.runtime.IMarshallingContext;
import org.jibx.runtime.IUnmarshallingContext;
import org.jibx.runtime.JiBXException;
import org.w3c.dom.Node;

public class JiBXUtil {
	
	public static Object unmarshalDocument(Node node, Class targetClass) throws JiBXException {
		return unmarshalDocument(new DOMSource(node), targetClass);
	}
	
	public static Object unmarshalDocument(Source source, Class targetClass) throws JiBXException {
		Object result = null;
		try {
			IUnmarshallingContext ctx = BindingDirectory.getFactory(
					targetClass).createUnmarshallingContext();
			result = ctx.unmarshalDocument(new StringReader(toString(source)));
		} catch (Exception e) {
			throw new JiBXException("Error unmarshalling XML to Object", e);
		}
		return result;
	}

	public static Source marshalDocument(Object src, String encoding) 
                                    throws JiBXException {
		Source result = null;
		
		try {
			ByteArrayOutputStream bOut = new ByteArrayOutputStream();
			IMarshallingContext ctx = BindingDirectory.getFactory(src.getClass())
			            .createMarshallingContext();
			ctx.marshalDocument(src, "UTF-8", null, bOut);
			result = new StreamSource(new ByteArrayInputStream(bOut.toByteArray()));
		} catch (Exception e) {
			throw new JiBXException("Error marshalling XML to Object",e);
		}
		return result;
	}
	
	private static String toString(Source source) throws TransformerException {
    	TransformerFactory tf = TransformerFactory.newInstance();
    	StringWriter sw = new StringWriter();
    	Transformer trans = tf.newTransformer();
    	trans.transform(source, new StreamResult(sw));
    	String result = sw.toString();
    	System.out.println("result " + result);
    	return result;
	}
}
